package
{
	import flash.display.Sprite;
	import flash.events.KeyboardEvent;
	import flash.text.TextField;
	import flash.text.TextFieldType;
	import flash.ui.Keyboard;

	public class Debugger extends Sprite
	{
		private const inputHeight:uint = 50;
		private var output:TextField;
		private var input:TextField;
		private var history:Array; /* debugger history - infinite for now. */
		private static var hbrowse:uint = 0;
		private var msgnum:uint = 0;
		private var scroll:uint = 0;
		
		/* TODO: RAM Hex Editor */
		/* TODO: RAM Disassembler */
		
		public function Debugger(xpos:uint, ypos:uint, hsize:uint, vsize:uint)
		{
			super();
			output = new TextField;
			input = new TextField;
			
			history = new Array();
			
			/* Set up debug console's output box (top part) */
			output.x = xpos;
			output.y = ypos;
			output.height = vsize - inputHeight;
			output.width = hsize;
			output.wordWrap = true;
			output.multiline = true;
			output.background = true;
			output.border = true;
			output.text = "***DEBUG CONSOLE***\n";
			
			/* Set up debug console's input box (bottom part) */
			input.x = xpos;
			input.y = vsize - inputHeight;
			input.height = inputHeight;
			input.width = hsize;
			input.type = TextFieldType.INPUT;
			input.wordWrap = true;
			input.multiline = false;
			input.background = true;
			input.border = true;
			
			input.addEventListener(KeyboardEvent.KEY_DOWN, doKey);
			
			addChild(output);
			addChild(input);
		}
		
		private function doKey(ev:KeyboardEvent):void {
			switch (ev.keyCode) {
				case Keyboard.ENTER:					
					doCommand(input.text);
					input.text = "";
					break;
				case Keyboard.UP:
					if (hbrowse < history.length) hbrowse++;
					input.text = history[history.length - hbrowse];
					break;
				case Keyboard.DOWN:
					if (hbrowse > 0) hbrowse--;
					input.text = history[history.length - hbrowse];
					break;
					/*
				default:
					hbrowse = 0;
					break;
					*/
			}
		}
		
		private var commands:Array = new Array();		
		
		private function doCommand(cmd:String):void {
			history.push(cmd);
			switch (cmd) {
				case "clear":
					clear();
					break;
				case "reset":
					clear();
					msgnum = 0;
					break;
				default:
					if (commands[cmd]) (commands[cmd] as Function).call();
					break;
			}
		}

		public function addCommand(sig:String, op:Function):void {
			commands[sig] = op;
		}
				
		public function print(msg:String):void {
			output.appendText((msgnum++) + ": " + msg + "\n");
			output.scrollV = output.maxScrollV;
		}
		
		public function clear():void {
			output.text = "";
		}
				
	}
}